package io.gitee.kotle.player.ui.view.exo

import android.view.MotionEvent
import android.view.View
import io.gitee.kotle.player.core.impl.exoplayer.IExoPlayerMode
import io.gitee.kotle.player.core.isPlaying
import io.gitee.kotle.player.core.seekPercentage
import io.gitee.kotle.player.ui.setScreenBrightnessSlide
import io.gitee.kotle.player.ui.setVolume
import io.gitee.kotle.player.ui.view.PlayerGestureDetectorHelper
import kotlin.math.max
import kotlin.math.min

/**
 * 手势操作回调类
 * 可自定义更改默认实现逻辑
 */
open class ExoPlayerGestureDetectorHelper(
    private val view: View,
    private val config: ExoPlayerViewConfig<IExoPlayerMode>
) : PlayerGestureDetectorHelper(view) {
    /**
     * 记录上一次的播放倍速
     */
    private var lastSpeed: Float? = null

    /**
     * 长按默认倍速
     */
    private val longPressedSpeed
        get() = config.longPressVideoSpeed.value ?: 3f

    /**
     * 播放器对象
     */
    private val player
        get() = config.player

    /**
     * 调节亮度
     */
    override fun swipeLeft(totalDistance: Float, currentOffset: Float, action: Int) {
        super.swipeLeft(totalDistance, currentOffset, action)
        val swipePercentage = getSwipePercentage(currentOffset, false)
        config.screenBrightness.value = view.setScreenBrightnessSlide(swipePercentage)
        if (action == MotionEvent.ACTION_UP) {
            config.screenBrightness.value = null
        }
    }

    /**
     * 调节音量
     */
    override fun swipeRight(totalDistance: Float, currentOffset: Float, action: Int) {
        super.swipeRight(totalDistance, currentOffset, action)
        val swipePercentage = getSwipePercentage(currentOffset, false)
        val isAdjustSystemVolume = config.isAdjustSystemVolume.value ?: true
        val currentVolume = if (isAdjustSystemVolume) {
            view.setVolume(swipePercentage)
        } else {
            var newVolume = swipePercentage + player.volume
            newVolume = max(0f, newVolume)
            newVolume = min(1f, newVolume)
            player.volume = newVolume
            newVolume
        }
        config.currentVolume.value = currentVolume
        if (action == MotionEvent.ACTION_UP) {
            config.currentVolume.value = null
        }
    }

    /**
     * 调节进度
     */
    private var lastPlayMs = 0L
    override fun swipeHorizontal(totalDistance: Float, currentOffset: Float, action: Int) {
        super.swipeHorizontal(totalDistance, currentOffset, action)
        if (action == MotionEvent.ACTION_DOWN && player.duration > 0L) {
            lastPlayMs = player.currentPosition
        }
        if (lastPlayMs > 0L) {
            val allowMax = config.allMaxSeekProgressMs.value ?: player.duration
            var newPercentage =
                (lastPlayMs - getSwipePercentage(totalDistance, true) * allowMax) / player.duration
            if (newPercentage <= 0f) {
                newPercentage = 0f
            }
            if (newPercentage >= 1f) {
                newPercentage = 1f
            }
            config.seekBarProgress.value = Pair(false, newPercentage)
            if (action == MotionEvent.ACTION_UP) {
                //先设置进度
                player.seekPercentage(newPercentage)
                //必须在进度之后调用
                config.seekBarProgress.value = Pair(true, newPercentage)
                lastPlayMs = 0L
            }
        }
    }


    private fun getSwipePercentage(totalDistance: Float, isHorizontal: Boolean): Float {
        val max = if (isHorizontal) view.width else view.height
        return totalDistance / max
    }


    override fun onDoubleTap(e: MotionEvent): Boolean {
        val enableDoubleClick = config.enableDoubleClick.value ?: true
        if (enableDoubleClick) {
            if (player.isPlaying) {
                player.pause()
            } else {
                player.play()
            }
        }
        return enableDoubleClick
    }

    override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
        config.singleTapConfirmed.value = !(config.singleTapConfirmed.value ?: false)
        return true
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        config.motionEvent.value = event
        if (event?.action == MotionEvent.ACTION_UP ||
            event?.action == MotionEvent.ACTION_CANCEL
        ) {
            config.longPressEvent.value = null
            config.motionEvent.value = null
            val speed = lastSpeed
            if (speed != null) {
                lastSpeed = null
                player.speed = speed
            }
        }
        return super.onTouchEvent(event)
    }


    override fun onLongPress(e: MotionEvent) {
        super.onLongPress(e)
        val currentSpeed = player.speed
        if (longPressedSpeed != currentSpeed) {
            lastSpeed = currentSpeed
            player.speed = longPressedSpeed
            config.longPressEvent.value = longPressedSpeed
        }
    }
}